package com.eascs.admin.o2o.badloan.controller;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.dubbo.config.annotation.Reference;
import com.eascs.admin.common.utils.StringUtils;
import com.eascs.admin.o2o.badloan.entity.O2oBadLoanPageVo;
import com.eascs.admin.o2o.badloan.entity.O2oBadRecordEntity;
import com.eascs.admin.o2o.badloan.entity.O2oCacleEntity;
import com.eascs.admin.o2o.badloan.form.O2oCacleTForm;
import com.eascs.admin.o2o.badloan.service.ICancelService;
import com.eascs.admin.o2o.badloan.service.O2oBadLoanService;
import com.eascs.admin.o2o.badloan.service.O2oCancleServiceImpl;
import com.eascs.admin.o2o.internal.util.BaseUtils;
import com.eascs.admin.o2o.internal.util.StatusContexts;
import com.eascs.admin.o2o.loan.entity.O2oEaLoanDataEnity;
import com.eascs.admin.o2o.loan.entity.O2oEaLoanDataTdEnity;
import com.eascs.admin.o2o.loan.entity.O2oLoanUserEntity;
import com.eascs.admin.o2o.loan.entity.O2oLoanapplyEntity;
import com.eascs.admin.o2o.loan.service.O2oLoanUserService;
import com.eascs.admin.o2o.loan.service.O2oLoanapplyService;
import com.eascs.admin.o2o.settle.entity.O2oSettleEntity;
import com.eascs.admin.o2o.settle.service.O2oSettleService;
import com.eascs.admin.o2o.settle.vo.O2oSettleVo;
import com.eascs.app.dao.PageResult;
import com.eascs.app.log.Logger;
import com.eascs.app.log.LoggerFactory;
import com.eascs.bankAccount.BankAccountService;
import com.eascs.brand.service.O2oBrandService;
import com.eascs.brand.vo.BrandAndPartnerVo;
import com.eascs.common.doc.excel.ExcelApiHelper;
import com.eascs.common.doc.excel.RowReadHandler;
import com.eascs.common.exception.RuntimeIOException;
import com.eascs.common.util.DateUtils;
import com.eascs.common.util.IoUtil;
import com.eascs.common.util.StringUtil;
import com.eascs.common.util.UrlUtil;
import com.eascs.crm.common.entity.CustomerBasicInfoEntity;
import com.eascs.crm.common.service.ICustomerInfoService;
import com.eascs.crm.common.vo.QueryCustomerVO;
import com.eascs.datalist.entity.O2oDataListEntity;
import com.eascs.datalist.service.O2oDataListService;
import com.eascs.file.FileService;
import com.eascs.file.FileTypeConstants;
import com.eascs.loan.controller.O2oPaymentsRestController;
import com.eascs.loan.entity.O2oBankLoanData;
import com.eascs.loan.form.O2oLoanForm;
import com.eascs.loan.form.O2oPaymentsForm;
import com.eascs.loan.service.O2oLoanService;
import com.eascs.loan.service.impl.O2oPaymentsServiceImpl;
import com.eascs.loan.vo.O2oRepaymentRecordVo;
import com.eascs.pay.entity.O2oPayEntity;
import com.eascs.pay.service.impl.O2oPayServiceImpl;
import com.eascs.site.controller.BaseRestController;
import com.eascs.site.page.PaginationInfo;
import com.eascs.site.page.SelectDataOption;
import com.eascs.site.view.BaseRestResult;
import com.eascs.site.view.HtmlRestResult;
import com.eascs.site.view.PaginationRestResult;
import com.eascs.site.view.ViewContext;
import com.eascs.site.view.button.AjaxButton;
import com.eascs.site.view.button.Button;
import com.eascs.site.view.button.ButtonHelper;
import com.eascs.site.view.button.ShowButtonFilter;
import com.eascs.web.sso.User;
import com.eascs.web.sso.UserHolder;
import com.eascs.workflow.common.entity.wf.ProcessTemplate;
import com.eascs.workflow.common.service.sys.SysOrgService;
import com.eascs.workflow.common.service.wf.WorkFlowService;
import com.eascs.workflow.common.vo.ModelResult;
import com.eascs.workflow.common.vo.WFRequestParam;

@RestController
@RequestMapping("/rbadloan")
public class O2oBadloanRestController extends BaseRestController {

	private static Logger log = LoggerFactory.getLogger(O2oBadloanRestController.class);

	@Autowired
	private O2oLoanapplyService loanService;

	@Reference
	private ICustomerInfoService customerInfoService;
	
	@Autowired
	private O2oBadLoanService service;

	@Autowired
	O2oCancleServiceImpl o2oCancleServiceImpl;

	@Autowired
	private O2oPaymentsServiceImpl o2oPaymentsServiceImpl;

	@Autowired
	private BaseUtils baseUtils;

	@Value("${o2o.admin.newRepaymentUrl}")
	String startUrl;

	@Reference
	private WorkFlowService workFlowService;
	@Reference
	private SysOrgService sysOrgService;
	@Reference
	private ICancelService iCancelService;

	@Autowired
	private FileService fileService;
	
	@Autowired
	private O2oLoanapplyService o2oLoanapplyService;

	// @Autowired
	// private O2oPayServiceImpl o2oPayServiceImpl;

	@Autowired
	private O2oDataListService o2oDataListService;
	@Autowired
	private O2oLoanUserService o2oLoanUserService;
	@Autowired
	private O2oBrandService o2oBrandService;
	@Autowired
	private O2oLoanService o2oLoanService;
	@Autowired
	private BankAccountService bankAccountService;

	@RequestMapping("/find_loaninfo")
	public BaseRestResult<String> findLoanInfo(String billCode, String upLoandFile, String referId, String lcz) {
		O2oLoanapplyEntity loanapply = loanService.fingByBillCode(billCode);
		log.info("find billCode：{}", billCode);
		log.info("find loanapply：{}", loanapply);
		if (loanapply != null && loanapply.getLoanId() != null) {
			O2oLoanUserEntity loanUser = o2oLoanUserService.findById(loanapply.getLoanId(), loanapply.getLoanapplyNo());
			ViewContext.put("loanUser", loanUser);
		}
		BrandAndPartnerVo brand = o2oBrandService.queryCodeAndName(loanapply.getLoanapplyNo());
		O2oBankLoanData bankData = o2oLoanService.queryBillCode(loanapply.getBillCode());

		ViewContext.put("bankData", bankData);
		ViewContext.put("brand", brand);
		ViewContext.put("loanapply", loanapply);
		ViewContext.put("referId", referId);
		ViewContext.put("lcz", lcz);
		return new HtmlRestResult("badloan/loan_info");
	}

	@RequestMapping("/find_file")
	public BaseRestResult<String> findFile(String recordId) {
		List<O2oDataListEntity> o2oDataList = o2oDataListService.findByEntityList(recordId);
		ViewContext.put("o2oDataList", o2oDataList);
		return new HtmlRestResult("badloan/badloan_file");
	}

	/**
	 * @Description:
	 * 				<p>
	 *               动态表单上传文件
	 *               </p>
	 * @author CXW
	 * @date 2016年12月26日 下午1:38:01
	 * @version V1.0
	 */
	@RequestMapping("/upload_file")
	public BaseRestResult<String> uploadFile(String recordId, String isupload) {
		String code = "'" + FileTypeConstants.DALIST_TYPE_RPMENT + "','" + FileTypeConstants.DALIST_TYPE_REPAYMENT + "'";
		PageResult<Object[]> pageResult = loanService.findO2oDataListEntityById(recordId, code);
		String titles[] = { "附件类型", "文件名", "提交人", "提交时间", "更新时间" };
		Button[] titleButtons = new Button[] { null, ButtonHelper.createOpenButton(null, "/file/download?datalistno=") };
		PaginationInfo paginationInfo = new PaginationInfo(pageResult, titles);
		paginationInfo.setTitleButtons(titleButtons);
		paginationInfo.setBuildPagingNavigation(false);
		paginationInfo.setFirstRenderColumnIndex(1);
		paginationInfo.setBuildRowNumber(true);
		ViewContext.put("paginationInfo", paginationInfo);// 个人附件
		ViewContext.put("recordId", recordId);
		ViewContext.put("isupload", isupload);
		return new HtmlRestResult("badloan/upload_file");
	}

	/**
	 * @Description:
	 * 				<p>
	 *               总部贷后复核-动态表单
	 *               </p>
	 * @author CXW
	 * @date 2016年12月23日 上午9:40:59
	 * @version V1.0
	 */
	@RequestMapping("/find_payment")
	public BaseRestResult<String> findNowPayment(String referId) {
		O2oBadRecordEntity badRecordEntity = service.getByBadRecordID(referId);
		int number = service.findCountByBillCode(badRecordEntity.getBillCode());
		getBankAccount();
		ViewContext.put("number", number);
		ViewContext.put("entity", badRecordEntity);
		return new HtmlRestResult("badloan/payments_list");
	}

	/**
	 * @Description:
	 * 				<p>
	 *               总部财务复核-动态表单
	 *               </p>
	 * @author CXW
	 * @date 2016年12月23日 上午9:40:59
	 * @version V1.0
	 */
	@RequestMapping("/find_payment_view")
	public BaseRestResult<String> findNowPaymentView(String referId, String type) {
		O2oBadRecordEntity badRecordEntity = service.getByBadRecordID(referId);
		// badRecordEntity.setNowShouldInterest(calculationInterest(badRecordEntity));
		int number = service.findCountByBillCode(badRecordEntity.getBillCode());
		ViewContext.put("number", number);
		ViewContext.put("type", type);
		ViewContext.put("entity", badRecordEntity);
		getBankAccount();
		return new HtmlRestResult("badloan/payments_list_view");
	}

	/**
	 * @Description:
	 * 				<p>
	 *               计算利息
	 *               </p>
	 * @author CXW
	 * @date 2016年12月27日 下午1:29:58
	 * @version V1.0
	 */
	public BigDecimal calculationInterest(O2oBadRecordEntity badRecordEntity) {
		int number = service.findCountByBillCode(badRecordEntity.getBillCode());
		BigDecimal interest = new BigDecimal(0);
		Calendar nowDate = Calendar.getInstance(), oldDate = Calendar.getInstance();
		nowDate.setTime(new Date());// 设置为当前系统时间
		if (number < 1) {// 第一笔代偿利息起始计算日以代偿流程中的付款时间为准
			oldDate.setTime(badRecordEntity.getNewTime());// 设置为1990年（6）月29日
		} else {// 非第一笔代偿利息以上一次流程中总部财务复核的“收款时间”开始计算
			String dateStr = service.findPayDateByBillCode(badRecordEntity.getBillCode());// 查询“收款时间”
			Date date = DateUtils.formateStandDate(dateStr);
			oldDate.setTime(date);
		}
		long timeNow = nowDate.getTimeInMillis();
		long timeOld = oldDate.getTimeInMillis();
		long nowTime = (timeNow - timeOld) / (1000 * 60 * 60 * 24);// 化为天
		interest = badRecordEntity.getNowShouldCapital().multiply(new BigDecimal(nowTime - 1)).multiply(new BigDecimal(0.0125 / 30));
		interest = interest.setScale(2, RoundingMode.HALF_UP);
		log.info("回款计算利息，判断利息是否大于0：{}", interest.compareTo(BigDecimal.ZERO));
		if (interest.compareTo(BigDecimal.ZERO) == -1) {// 小于0
			interest = new BigDecimal("0.00");
		}
		log.info("返回利息为：{}", interest);
		return interest;
	}

	/**
	 * @param badRecordEntity
	 * @description
	 * 				<p>
	 *              保存平台经理节点动态表单
	 *              </p>
	 * @author CXW
	 * @date 2016年8月26日 下午5:04:44
	 * @version V1.0
	 * @return BaseRestResult<String>
	 */
	@RequestMapping("/update_payment")
	public BaseRestResult<String> updateNowPayment(O2oBadRecordEntity badRecordEntity) {
		if (StringUtil.isEmpty(badRecordEntity.getThisPaymentPrincipal())) {
			return BaseRestResult.warn("实际收款金额不能为空");
		}
		if (StringUtil.isEmpty(badRecordEntity.getThisPaymentDate())) {
			return BaseRestResult.warn("收款时间不能为空");
		}
		if (StringUtil.isEmpty(badRecordEntity.getPayAccount())) {
			return BaseRestResult.warn("收款账户不能为空");
		}
		O2oBadRecordEntity entity = service.getByBadRecordID(badRecordEntity.getId());
		entity.setPayAccount(badRecordEntity.getPayAccount());
		entity.setThisPaymentDate(badRecordEntity.getThisPaymentDate());
		entity.setThisPaymentPrincipal(badRecordEntity.getThisPaymentPrincipal());
		int i = service.updateByBadRecordID(entity);
		if (i > 0) {
			return BaseRestResult.info("保存成功");
		} else {
			return BaseRestResult.warn("保存失败");
		}
	}

	/**
	 * @Title: delPayments
	 * @Description: 删除还款计划信息
	 * @author 张庆奇
	 * @param payments_id
	 * @return
	 * @return BaseRestResult<?>
	 * @throws @date
	 *             2016年6月21日 下午2:28:13
	 */
	@RequestMapping("/delPayments")
	public BaseRestResult<?> delPayments(String payments_id, String bill_code) {
		boolean flag = false;
		BaseRestResult<?> result = null;
		flag = o2oPaymentsServiceImpl.delNewPayments(payments_id);
		if (flag == true) {
			result = BaseRestResult.info("删除成功").andRefresh();
		} else if (flag == false) {
			result = BaseRestResult.error("删除失败").andRefresh();
		}
		return result;
	}

	/**
	 * @param badRecordEntity
	 * @description
	 * 				<p>
	 *              保存平台经理节点动态表单
	 *              </p>
	 * @author CXW
	 * @date 2016年8月26日 下午5:04:44
	 * @version V1.0
	 * @return BaseRestResult<String>
	 */
	@RequestMapping("/updateRe")
	public BaseRestResult<String> updateRe(O2oBadRecordEntity badRecordEntity) {
		if (StringUtil.isEmpty(badRecordEntity.getPayee())) {
			return BaseRestResult.warn("打款人不能为空");
		}
		if (StringUtil.isEmpty(badRecordEntity.getLiquiId())) {
			return BaseRestResult.warn("清收人不能为空");
		}
		if (StringUtil.isEmpty(badRecordEntity.getPayTime())) {
			return BaseRestResult.warn("收款时间不能为空");
		}
		if (StringUtil.isEmpty(badRecordEntity.getPayAmount())) {
			return BaseRestResult.warn("回款金额不能为空");
		}
		// if (badRecordEntity.getPayAccount().equals("OTHER")) {
		// if (StringUtil.isEmpty(badRecordEntity.getPayAccountOther())) {
		// return BaseRestResult.warn("收款账户不能为空");
		// } else {
		// badRecordEntity.setPayAccount(badRecordEntity.getPayAccountOther());
		// }
		// }
		// if (isUploadFile(badRecordEntity.getId())) {
		O2oBadRecordEntity entity = service.getByBadRecordID(badRecordEntity.getId());
		entity.setPayee(badRecordEntity.getPayee());
		entity.setLiquiId(badRecordEntity.getLiquiId());
		entity.setLiquiName(badRecordEntity.getLiquiName());
		entity.setPayTime(badRecordEntity.getPayTime());
		entity.setPayAmount(badRecordEntity.getPayAmount());
		int i = service.updateByBadRecordID(entity);
		if (i > 0) {
			return BaseRestResult.info("保存成功");
		} else {
			return BaseRestResult.warn("保存失败");
		}
		// } else {
		// return BaseRestResult.warn("请上传打款凭证");
		// }
	}

	/**
	 * @Description:
	 * 				<p>
	 *               查看还款详情
	 *               </p>
	 * @author CXW
	 * @date 2016年9月7日 下午4:27:04
	 * @version V1.0
	 * @param
	 * @return BaseRestResult<String>
	 */
	@RequestMapping("/recordView")
	public BaseRestResult<String> recordView(O2oRepaymentRecordVo entity) {
		log.info("工作流访问回款详情：参数billCode：【{}】，referId:【{}】", entity.getBillCode(), entity.getReferId());
		O2oBadRecordEntity entity1 = service.getByBadRecordID(entity.getReferId());
		String approvalUrl = baseUtils.getApprovalUrl(entity.getNodeAuditorId(), ProcessTemplate.SYSTEM_MODULE_O2O);// 审批代办列表详情URL
		ViewContext.put("approvalUrl", approvalUrl);
		String agreeUrl = baseUtils.getApprovalAgreeUrl(entity.getReferId(), entity.getNodeAuditorId(), ProcessTemplate.SYSTEM_MODULE_O2O);
		ViewContext.put("agreeUrl", agreeUrl);
		ViewContext.put("referId", entity.getReferId());
		ViewContext.put("approvalStatus", entity.getApprovalStatus());
		ViewContext.put("billCode", entity1.getBillCode());
		return HtmlRestResult.popHtmlFragment("badloan/approl");
	}

	/**
	 * @Description:
	 * 				<p>
	 *               查看还款详情还款记录
	 *               </p>
	 * @author CXW
	 * @date 2016年9月7日 下午4:27:04
	 * @version V1.0
	 * @param
	 * @return BaseRestResult<String>
	 */
	@RequestMapping("/findRecordView")
	public BaseRestResult<String> findRecordView(String id) {
		O2oBadRecordEntity entity = service.getByBadRecordID(id);
		log.info("工作流访问回款详情：参数billCode：【{}】，referId:【{}】", entity.getBillCode(), entity.getId());
		String agreeUrl = baseUtils.getApprovalAgreeUrl(entity.getId(), null, ProcessTemplate.SYSTEM_MODULE_O2O);
		ViewContext.put("agreeUrl", agreeUrl);
		ViewContext.put("billCode", entity.getBillCode());
		ViewContext.put("referId", entity.getId());
		ViewContext.put("loanDataId", entity.getLoanDataId());
		ViewContext.put("status", entity.getFlowStatus());
		return HtmlRestResult.popHtmlFragment("badloan/approl_detail");
	}

	/**
	 * @Description:
	 * 				<p>
	 *               信贷经理节点-动态表单查询收款信息
	 *               </p>
	 * @author CXW
	 * @date 2016年12月20日 下午4:48:26
	 * @version V1.0
	 * @param
	 * @return BaseRestResult<String>
	 */
	@RequestMapping("/findRecord")
	public BaseRestResult<String> findRecordById(String referId) {
		O2oBadRecordEntity badRecordEntity = service.getByBadRecordID(referId);
		ViewContext.put("entity", badRecordEntity);
		return new HtmlRestResult("badloan/repayment");
	}

	@Autowired
	O2oSettleService o2oSettleService;

	@RequestMapping("/start")
	public BaseRestResult<String> startUp(String bankLoanId) {
		O2oSettleVo vo = new O2oSettleVo();
		vo.setEaLoadId(bankLoanId);
		O2oSettleEntity o2oSettleEntity = o2oSettleService.findEntity(vo);
		if (o2oSettleEntity != null) {
			if (o2oSettleEntity.getFlowStatus().equals(StatusContexts.O2O_BANK_RUN)) {
				return BaseRestResult.warn("该单有一个结清流程，不能发起回款！");
			} else if (o2oSettleEntity.getFlowStatus().equals(StatusContexts.O2O_BANK_CLO)) {
				return BaseRestResult.warn("该单已结清，不能发起回款！");
			}
			//是否已删除，已删除不能发起流程
			if (o2oSettleEntity.getIsDelete().equals(StatusContexts.O2O_YES)) {
				return BaseRestResult.warn("该单已被删除，不能发起回款！");
			}
		}
		// 查询不良放款
		O2oEaLoanDataEnity dataEnity = service.findById(bankLoanId);
		log.info("查询到不良放款信息：{}", dataEnity);
		O2oBadRecordEntity o2oBadRecordEntity1;
		O2oBadRecordEntity badRecordEntity = new O2oBadRecordEntity();
		if (dataEnity != null) {
			badRecordEntity.setBillCode(dataEnity.getBillCodeEa());
			badRecordEntity.setFlowStatus(StatusContexts.O2O_NEW);// 查询未发起流程的单号
			badRecordEntity.setLoanDataId(dataEnity.getId());
			o2oBadRecordEntity1 = service.findRecordByFlowStatus(badRecordEntity);
			log.info("查询未发起流程的单号：{}", o2oBadRecordEntity1);
		} else {
			o2oBadRecordEntity1 = service.getByBadRecordID(bankLoanId);
			log.info("查询未发起流程的单号：{}", o2oBadRecordEntity1);
		}
		if (o2oBadRecordEntity1 == null) {
			badRecordEntity.setFlowStatus(StatusContexts.O2O_BANK_RUN);// 查询已发起流程的单号
			o2oBadRecordEntity1 = service.findRecordByFlowStatus(badRecordEntity);
			if (o2oBadRecordEntity1 != null) {
				// 如果流程已经启动则等流程走完后再次发起
				return BaseRestResult.warn("已有一个流程在流程中，不能重复发起");
			} else {
				badRecordEntity.setFlowStatus(StatusContexts.O2O_BANK_CLO);// 查询流程结束的单号
				o2oBadRecordEntity1 = service.findRecordByFlowStatus(badRecordEntity);
				O2oLoanapplyEntity loanapplyEntity = loanService.findBillCode1(dataEnity.getBillCodeEa());
				if (o2oBadRecordEntity1 != null) {
					if (o2oBadRecordEntity1.getNowArrears() != null && o2oBadRecordEntity1.getNowArrears().compareTo(BigDecimal.ZERO) <= 0) {
						// 如果贷款已经还清，不能再发起流程
						return BaseRestResult.warn("当前欠还余额已为0，不能再发起流程");
					} else {// 如果未结清，则再插入一条数据并启动流程
						o2oBadRecordEntity1 = new O2oBadRecordEntity();
						o2oBadRecordEntity1.setLoanDataId(dataEnity.getId());// EA放款ID
						o2oBadRecordEntity1.setBillCode(dataEnity.getBillCodeEa());// 贷款单号
						o2oBadRecordEntity1.setLoanapplyNo(loanapplyEntity.getLoanapplyNo());
						o2oBadRecordEntity1.setIsDelete(StatusContexts.O2O_NO);// 不删除（只存数据库不显示）
						o2oBadRecordEntity1.setNewTime(new Date());// 发生时间
						String billCode = dataEnity.getBillCodeEa();
						String loanDataId = dataEnity.getId();
						String nowAreas = service.getNowAreas(billCode, loanDataId) == null ? "0" : service.getNowAreas(billCode, loanDataId);
						o2oBadRecordEntity1.setNowArrears(new BigDecimal(nowAreas));// 本次余额
						o2oBadRecordEntity1.setNowShouldCapital(dataEnity.getPayAmount());// 应还本金（只存数据库不显示）
						o2oBadRecordEntity1.setFlowStatus(StatusContexts.O2O_NEW);// 流程状态，初始化为NEW
						log.info("查询不良回款信息：{}", o2oBadRecordEntity1);
						service.insertRecord(o2oBadRecordEntity1);
					}
				} else {// 如果都是空数据，则插入一条数据并启动流程
					o2oBadRecordEntity1 = new O2oBadRecordEntity();
					o2oBadRecordEntity1.setLoanDataId(dataEnity.getId());// EA放款ID
					o2oBadRecordEntity1.setBillCode(dataEnity.getBillCodeEa());// 贷款单号
					o2oBadRecordEntity1.setLoanapplyNo(loanapplyEntity.getLoanapplyNo());
					o2oBadRecordEntity1.setIsDelete(StatusContexts.O2O_NO);// 不删除（只存数据库不显示）
					o2oBadRecordEntity1.setNewTime(new Date());// 发生时间
					o2oBadRecordEntity1.setNowArrears(dataEnity.getPayAmount());// 本次余额
					o2oBadRecordEntity1.setNowShouldCapital(dataEnity.getPayAmount());// 应还本金（只存数据库不显示）
					o2oBadRecordEntity1.setFlowStatus(StatusContexts.O2O_NEW);// 流程状态，初始化为NEW
					log.info("查询不良回款信息：{}", o2oBadRecordEntity1);
					service.insertRecord(o2oBadRecordEntity1);
				}
			}
		}
		ModelResult<Boolean> model = startPayBack(o2oBadRecordEntity1);
		if (model.isSuccess()) {
			User user = UserHolder.getUser();
			o2oBadRecordEntity1.setFlowStartTime(new Date());
			o2oBadRecordEntity1.setFlowStatus(StatusContexts.O2O_BANK_RUN);
			o2oBadRecordEntity1.setFlowStartUserno(user.getNo());
			o2oBadRecordEntity1.setFlowStartUsername(user.getCname());
			service.updateByBadRecordID(o2oBadRecordEntity1);
			return BaseRestResult.info("发起成功").andRedirect("/badloan/alllist?billCode=" + o2oBadRecordEntity1.getBillCode());
		} else {
			log.error("发起还款流程失败，失败原因：{}", model.getDetailStack());
			return BaseRestResult.warn(model.getErrMsg());
		}
	}

	/**
	 * 启动回款流程
	 */
	public ModelResult<Boolean> startPayBack(O2oBadRecordEntity badRecordEntity) { // 根据单号去启动流程
		ModelResult<Boolean> modelResult = new ModelResult<>();
		O2oLoanapplyEntity loan = new O2oLoanapplyEntity();
		loan = loanService.fingByBillCode(badRecordEntity.getBillCode());
		if (null == loan) {
			return modelResult.withError("error billCode O2O SQL not find", "贷款单号异常，请检查数据是否正常");
		}
		// 获取 o2opay对象
		WFRequestParam param = new WFRequestParam();
		param.setReferId(badRecordEntity.getId());
		param.setReferCode(badRecordEntity.getBillCode());
		// 回款流程的url
		param.setReferUrl(startUrl + "?billCode=" + loan.getBillCode() + "&recordId=" + badRecordEntity.getId());
		param.setSystemModule(ProcessTemplate.SYSTEM_MODULE_O2O);
		param.setProcessType(ProcessTemplate.PROECESS_TYPE_BACK_MONEY); // 修改成回款流程编号
		User user = UserHolder.getUser();
		param.setAppliedby(user.getNo());
		param.setAppliedbyName(user.getCname());
		param.setOrgNo(loan.getLtd());
		StringBuffer appliedDes = new StringBuffer("借款人:");
		appliedDes.append(loanService.findLoanUserEntity(loan.getLoanapplyNo(), loan.getLoanId()).getUserFullName());
		appliedDes.append("，放款金额:");
		java.text.DecimalFormat df = new java.text.DecimalFormat("0.00"); // 格式化，保留两位小数
		BigDecimal loanAmount = new BigDecimal(0);
		if ("EA".equals(loan.getLoanType()) || "FQ".equals(loan.getLoanType())) {
			loanAmount = service.findDataByBillCode(loan.getBillCode()).getLoanAmount();
		} else {
			loanAmount = o2oLoanService.queryBillCode(loan.getBillCode()).getLoanAmount();
		}
		appliedDes.append(df.format(loanAmount));
		param.setAppliedDes(appliedDes.toString());
		log.info("启动回款流程，参数有贷款id：【{}】，贷款编号：【{}】，系统模块：【{}】，流程类型：【{}】，经营平台id：【{}】，贷款摘要信息：【{}】", badRecordEntity.getId(), loan.getBillCode(), ProcessTemplate.SYSTEM_MODULE_O2O, param.getProcessType(), loan.getLtd(), appliedDes.toString());
		modelResult = workFlowService.instance(param);
		return modelResult;
	}

	/**
	 * 银行放款数据导入还款计划 刷新
	 * 
	 * @param file
	 * @param billCode
	 * @return
	 */
	@RequestMapping("/uploadBankExcel")
	public BaseRestResult<String> uploadBankExcel(@RequestParam(value = "file", required = false) MultipartFile file, String billCode, String mainId) {
		InputStream inputStream = null;
		try {
			inputStream = file.getInputStream();
			/** 获取文件的后缀 **/
			String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
			if (!".xls".equals(suffix)) {
				return BaseRestResult.warn("文件类型不对，请下载还款计划模板");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		O2oEaLoanDataEnity dataEnity = service.findById(mainId);
		String loanerName = dataEnity.getLoanerName();
		String idNum = dataEnity.getLoanerCard();
		try {
			ExcelApiHelper.readHandle(inputStream, new RowReadHandler() {
				@Override
				public void handle(int sheetIndex, int rowIndex, Object[] rowDatas) {
					check(sheetIndex, rowIndex, rowDatas, 0, billCode, loanerName, idNum, mainId);
				}
			});
		} catch (RuntimeException e) {
			String message = e.getMessage();
			message = e.getMessage().substring(27, message.length());
			return BaseRestResult.warn(message);
		}
		InputStream inputStream1 = null;
		try {
			inputStream1 = file.getInputStream();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			ExcelApiHelper.readHandle(inputStream1, new RowReadHandler() {
				@Override
				public void handle(int sheetIndex, int rowIndex, Object[] rowDatas) {
					check(sheetIndex, rowIndex, rowDatas, 1, billCode, loanerName, idNum, mainId);
				}
			});

		} catch (RuntimeException e) {
			String message = e.getMessage();
			message = e.getMessage().substring(27, message.length());
			return BaseRestResult.warn(message);

		}
		return BaseRestResult.buildClosestReloadResult();
	}

	/**
	 * @Title: check 校验数据
	 * @Description:
	 * @author 张庆奇
	 * @param sheetIndex
	 * @param rowIndex
	 * @param rowDatas
	 * @return void
	 * @throws @date
	 *             2016年6月22日 下午4:07:14
	 */
	private void check(int sheetIndex, int rowIndex, Object[] rowDatas, int type, String billCode, String name, String idNumber, String mainId) {

		String periods = "";
		String paymentsDate = "";
		String residualPrincipal = "";
		String payPrincipal = "";
		String payInterest = "";
		String payType = "";
		if (sheetIndex == 0 && rowIndex > 0) {
			for (int i = 0; i < rowDatas.length; i++) {
				if (i == 0) {
					periods = String.valueOf(rowDatas[0] == null ? "" : rowDatas[0]);
				} else if (i == 1) {
					paymentsDate = String.valueOf(rowDatas[1] == null ? "" : rowDatas[1]);
				} else if (i == 2) {
					residualPrincipal = String.valueOf(rowDatas[2] == null ? "" : rowDatas[2]);
				} else if (i == 3) {
					payPrincipal = String.valueOf(rowDatas[3] == null ? "" : rowDatas[3]);
				} else if (i == 4) {
					payInterest = String.valueOf(rowDatas[4] == null ? "" : rowDatas[4]);
				} else if (i == 5) {
					payType = String.valueOf(rowDatas[5] == null ? "" : rowDatas[5]);
				}

			}
			String message = "第" + rowIndex + "行：";
			if (StringUtil.isEmpty(billCode) && StringUtil.isEmpty(name) && StringUtil.isEmpty(idNumber)) {

				throw new RuntimeException("贷款单号、借款人姓名、借款人证件号三者必须有一个");

			}
			// 如果单款单号不为空，则查看是否存在，如果存在，则取出借款姓名、证件号码

			// 区分是老系统的单还是新系统的单
			if (!billCode.startsWith("O2O")) {
				if (StringUtil.isNotBlank(billCode)) {
					O2oLoanapplyEntity loanapply = loanService.fingByBillCode(billCode);
					if (loanapply == null) {
						throw new RuntimeException("贷款单号不存在");

					} else {
						QueryCustomerVO vo = new QueryCustomerVO();
						vo.setCustomer_id(loanapply.getLoanId());
					}
				}

				// 如果单款单号为空并且贷款证件不为空，则根据借款人证件、借款状态为申报完成：SF、已放款/审批通过：O
				if (StringUtil.isNull(billCode) && StringUtil.isNotBlank(idNumber)) {
					QueryCustomerVO vo = new QueryCustomerVO();
					vo.setId_number(idNumber);
					CustomerBasicInfoEntity info = customerInfoService.getCustomerBasicInfoEntity(vo);
					if (info == null) {
						throw new RuntimeException("没有找到借款人证件号为：" + idNumber + "该用户的信息");
					} else {
						List<O2oLoanapplyEntity> list = o2oPaymentsServiceImpl.findO2oLoanapplyEntity(info.getCustomerId());
						if (list != null) {
							if (list.size() == 0) {
								throw new RuntimeException("没有找到借款人证件号为" + idNumber + "该用户的申报完成或者放款完成的贷款申请信息");
							} else if (list.size() > 1) {
								throw new RuntimeException("[证件号为:" + idNumber + "的借款用户，需要手工录入相关信息，请在系统中查询贷款单号后，手动添加]");
							} else if (list.size() == 1) {

								billCode = list.get(0).getBillCode();
								name = info.getCustomerName();
							}

						}

					}

				}

				// 如果单款单号为空并且借款姓名不为空，身份证信息为空，则根据借款姓名、借款状态为申报完成：SF、已放款/审批通过：O查询billCode
				if (StringUtil.isNull(billCode) && StringUtil.isNull(idNumber) && StringUtil.isNotBlank(name)) {

					List<O2oLoanapplyEntity> list = o2oPaymentsServiceImpl.findO2oLoanapplyEntityByName(name);
					if (list != null) {
						if (list.size() == 0) {
							throw new RuntimeException("没有找到姓名为" + name + "该用户的申报完成或者放款完成的贷款申请信息");
						} else if (list.size() > 1) {
							throw new RuntimeException("[姓名:" + name + "的借款用户，需要手工录入相关信息，请在系统中查询贷款单号后，手动添加]");
						} else if (list.size() == 1) {

							billCode = list.get(0).getBillCode();
							if (StringUtil.isNotBlank(list.get(0).getLoanId())) {
								QueryCustomerVO vo = new QueryCustomerVO();
								vo.setCustomer_id(list.get(0).getLoanId());
								CustomerBasicInfoEntity info = customerInfoService.getCustomerBasicInfoEntity(vo);
								idNumber = info.getIdNumber();
							}

						}
					}
				}
			}

			if (periods == null || "".equals(periods)) {

				throw new RuntimeException(message + "期数不能为空");

			}

			if (paymentsDate == null || "".equals(paymentsDate)) {

				throw new RuntimeException(message + "计划还款时间不能为空");

			}
			if (residualPrincipal == null || "".equals(residualPrincipal)) {

				throw new RuntimeException(message + "剩余本金不能为空");

			}
			if (payPrincipal == null || "".equals(payPrincipal)) {

				throw new RuntimeException(message + "计划还款本金不能为空");

			}

			if (payInterest == null || "".equals(payInterest)) {

				throw new RuntimeException(message + "计划还款利息不能为空");

			}
			if (!isDouble(periods)) {
				throw new RuntimeException(message + "期数格式不正确");
			}

			if (!isValidDate(paymentsDate)) {
				throw new RuntimeException(message + "计划还款时间格式不正确");
			}

			if (!isDouble(residualPrincipal)) {
				throw new RuntimeException(message + "剩余本金格式不正确");
			}
			if (!isDouble(payPrincipal)) {
				throw new RuntimeException(message + "计划还款本金格式不正确");
			}
			if (!isDouble(payInterest)) {
				throw new RuntimeException(message + "计划还款利息格式不正确");
			}
			long num = Math.round(Double.parseDouble(periods));
			// 数据插入
			if (type == 1) {
				O2oEaLoanDataTdEnity dataTdEnity = new O2oEaLoanDataTdEnity();
				dataTdEnity.setDataType("2");
				dataTdEnity.setIsDel("N");
				dataTdEnity.setMainId(mainId);
				dataTdEnity.setOpratePsn(name);
				dataTdEnity.setOprateTime(new Date());
				dataTdEnity.setPayInterest(new BigDecimal(payInterest));
				dataTdEnity.setPaymentsDate(new java.sql.Date(DateUtils.formateStandDate(paymentsDate).getTime()));
				dataTdEnity.setPayPrincipal(new BigDecimal(payPrincipal));
				dataTdEnity.setPayTotal(new BigDecimal(payPrincipal).add(new BigDecimal(payInterest)));
				dataTdEnity.setPeriods(num);
				dataTdEnity.setRepaymentStatus("HKZ");
				dataTdEnity.setResidualPrincipal(new BigDecimal(residualPrincipal));
				dataTdEnity.setPayType(payType);
				int i = service.insert(dataTdEnity);
				if (i < 0) {
					throw new RuntimeException(message + "数据库保存异常");
				}
			}

		}

	}

	/**
	 * @Title: isDouble
	 * @Description: 判断是否为double类型
	 * @author CXW
	 * @param str
	 * @return
	 * @return boolean
	 * @throws @date
	 *             2016年12月20日 上午11:17:42
	 */
	private boolean isDouble(String str) {
		boolean flag = true;
		try {
			Double.parseDouble(str);
		} catch (Exception e) {
			flag = false;
		}
		return flag;

	}

	private boolean isValidDate(String str) {
		DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date date = (Date) formatter.parse(str);
			return str.equals(formatter.format(date));
		} catch (Exception e) {
			return false;
		}
	}

	public boolean isUploadFile(String loanapplyNo) {
		O2oDataListEntity data = fileService.getByRecordDataList(loanapplyNo);
		if (null == data) {
			return false;
		} else {
			return true;
		}
	}

	@RequestMapping("/download")
	public BaseRestResult<String> dowanload(HttpServletResponse httpServletResponse, HttpServletRequest request) {
		BaseRestResult<String> result = null;
		String file = O2oPaymentsRestController.class.getResource("/excelTemplate/bad_payments_plan.xls").getPath();

		OutputStream os = null;
		try {
			String outfile = "不良还款计划.xls";
			String userAgent = request.getHeader("User-Agent");
			byte[] bytes = userAgent.contains("MSIE") ? outfile.getBytes() : outfile.getBytes("UTF-8");
			outfile = new String(bytes, "ISO-8859-1"); // 各浏览器基本都支持ISO编码
			File f = new File(file);
			if (!f.exists())
				throw new RuntimeIOException("file not found");
			os = httpServletResponse.getOutputStream();
			httpServletResponse.reset();
			httpServletResponse.setHeader("Content-Disposition", "attachment; filename=" + outfile);
			httpServletResponse.setContentType("application/octet-stream; charset=utf-8");
			ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
			IoUtil.fileToOutputStream(f, byteArrayOutputStream);
			os.write(byteArrayOutputStream.toByteArray());
			os.flush();
		} catch (IOException e) {
			throw new RuntimeIOException(e);
		} finally {
			IoUtil.close(os);
		}

		return result;
	}

	@RequestMapping("/all_list")
	public PaginationRestResult findResult(O2oBadLoanPageVo vo) {
		vo.setPageSize(10);
		String findurl = "/rbadloan/all_list";
		String billCode = vo.getBillCode() == null ? "" : vo.getBillCode();
		String loanType = vo.getLoanType() == null ? "" : vo.getLoanType();
		String loanerName = vo.getLoanerName() == null ? "" : vo.getLoanerName();
		String province = vo.getProvince() == null ? "" : vo.getProvince();
		String loanDataId = vo.getLoanDataId() == null ? "" : vo.getLoanDataId();
		String firstTime = vo.getFirstTime() == null ? "" : vo.getFirstTime();
		String endTime = vo.getEndTime() == null ? "" : vo.getEndTime();
		String status = vo.getStatus() == null ? "" : vo.getStatus();
		String liquiName = vo.getLiquiName() == null ? "" : vo.getLiquiName();
		findurl = UrlUtil.appendUrl(findurl, "billCode", billCode);
		findurl = UrlUtil.appendUrl(findurl, "loanType", loanType);
		findurl = UrlUtil.appendUrl(findurl, "loanerName", loanerName);
		findurl = UrlUtil.appendUrl(findurl, "province", province);
		findurl = UrlUtil.appendUrl(findurl, "loanDataId", loanDataId);
		findurl = UrlUtil.appendUrl(findurl, "firstTime", firstTime);
		findurl = UrlUtil.appendUrl(findurl, "endTime", endTime);
		findurl = UrlUtil.appendUrl(findurl, "status", status);
		findurl = UrlUtil.appendUrl(findurl, "liquiName", liquiName);
		findurl = findurl + "&pageIndex=";
		PageResult<Object[]> pageResult = service.findByPageRecord(vo);
		String titles[] = { "贷款单号", "终端贷单号", "省份", "借款人姓名", "经办平台", "贷款类型", "本次回款金额", "本次发起时间", "本次实际还款时间", "清收人", "流程状态" };
		SelectDataOption[] selectDataOptions = { null, null, new SelectDataOption("O2OPROVINCE"), null, null, new SelectDataOption("BAD_LOAN_TYPE"), null, null, null, null, new SelectDataOption("PAY_STATUS") };
		// Button[] titleButtons = new Button[] {
		// ButtonHelper.createOpenButton(null, "/detail?billCode={2}") };
		Button findBtn = ButtonHelper.createAjaxButton("", "/rbadloan/findRecordView?id=");
		// findBtn.setShowButtonFilter(showButtonFilter);
		// Button delete = ButtonHelper.createAjaxButton("删除",
		// "/rbadloan/delete?loanDataId=", "updateNowAreas");
		// Button start_upButton = ButtonHelper.createAjaxButton("发起回款流程",
		// "/rbadloan/start?bankLoanId=", "startUpBadLoan");
		// delete.setShowButtonFilter(showButtondelete);
		// start_upButton.setShowButtonFilter(showButtondelete);
		Button[] detailButtons = new Button[] { findBtn };
		PaginationInfo o2oPagingInfo = new PaginationInfo(pageResult, titles, findurl);
		o2oPagingInfo.setBuildPagingNavigation(true);
		o2oPagingInfo.setFirstRenderColumnIndex(1);
		o2oPagingInfo.setTitleButtons(detailButtons);
		// o2oPagingInfo.setMoreButtons(detailButtons);
		o2oPagingInfo.setSelectDataOptions(selectDataOptions);
		o2oPagingInfo.setFormats(new Format[] { null, null, null, null, null, null, new DecimalFormat(",##0.00"), null });
		o2oPagingInfo.setRendTo("#result_list");
		ViewContext.put("vo", vo);
		return PaginationRestResult.buildPaginationRestResult(o2oPagingInfo);
	}

	/**
	 * @Description:
	 * 				<p>
	 *               删除还款记录
	 *               </p>
	 * @author CXW
	 * @date 2017年4月20日 下午1:31:57
	 * @version V1.0
	 */
	@RequestMapping("/delete")
	public BaseRestResult<String> delete(String loanDataId) {
		O2oBadRecordEntity dataEnity = service.getByBadRecordID(loanDataId);
		if (!dataEnity.getFlowStatus().equals(StatusContexts.O2O_NEW)) {
			return BaseRestResult.warn("该单在流程中或流程结束不能删除！");
		}
		dataEnity.setIsDelete(StatusContexts.O2O_YES);
		int i = service.updateByBadRecordID(dataEnity);
		if (i > 0) {
			return BaseRestResult.info("删除成功");
		} else
			return BaseRestResult.warn("删除失败");
	}

	/**
	 * 显示删除和查看按钮
	 */
	ShowButtonFilter showButtonFilter = new ShowButtonFilter() {

		@Override
		public boolean filter(Object param) {
			Object[] params = (Object[]) param;
			if (!params[10].equals(StatusContexts.O2O_NEW)) {
				return true;
			} else
				return false;
		}
	};
	/**
	 * 显示删除和查看按钮
	 */
	ShowButtonFilter showButtondelete = new ShowButtonFilter() {

		@Override
		public boolean filter(Object param) {
			Object[] params = (Object[]) param;
			if (params[10].equals(StatusContexts.O2O_NEW)) {
				return true;
			} else
				return false;
		}
	};

	@RequestMapping("/findHKdetail")
	public BaseRestResult<String> findHKdetail(String bankLoanId) {
		O2oEaLoanDataEnity dataEnity = service.findById(bankLoanId);
		hkHistory(dataEnity.getBillCodeEa());
		return HtmlRestResult.popHtmlFragment("/badloan/findHKdetail");
	}

	/**
	 * @Description:
	 * 				<p>
	 *               查询还款记录
	 *               </p>
	 * @author CXW
	 * @date 2016年9月8日 下午1:36:37
	 * @version V1.0
	 * @param billCode
	 * @return void
	 */
	public void hkHistory(String billCode) {
		O2oPaymentsForm o2oPaymentsForm = new O2oPaymentsForm();
		o2oPaymentsForm.setBillCode(billCode);
		o2oPaymentsForm.setPageSize(10);
		PageResult<Object[]> pageResult = o2oPaymentsServiceImpl.newRepaymentsList(o2oPaymentsForm);
		String titles[] = { "发生时间", "本次回款金额", "本次实际还款时间", "还款凭证", "本次回款后代偿余额", "流程状态" };//
		Button start_upButton = ButtonHelper.createAjaxButton("发起回款流程", "/rbadloan/start?id=", "startUpBadLoan");
		AjaxButton detailButton = new AjaxButton("查看回款流程", "/rbadloan/findRecordView?id=");
		start_upButton.setShowButtonFilter(showBottun);
		detailButton.setShowButtonFilter(showBottunDetail);
		Button[] dealButton = new Button[] { start_upButton, detailButton };
		PaginationInfo o2oPagingInfo = new PaginationInfo(pageResult, titles);
		Button fileButton = ButtonHelper.createOpenButton("查看", "/file/download?datalistno={4}");
		o2oPagingInfo.setTitleButtons(new Button[] { null, null, null, fileButton });
		o2oPagingInfo.setMoreButtons(dealButton);
		o2oPagingInfo.setBuildPagingNavigation(false);
		o2oPagingInfo.setFirstRenderColumnIndex(1);
		o2oPagingInfo.setBuildRowNumber(true);
		SelectDataOption[] selectDataOptions = { null, null, null, null, null, new SelectDataOption("PAY_STATUS") };
		o2oPagingInfo.setSelectDataOptions(selectDataOptions);
		ViewContext.put("o2oPagingInfo", o2oPagingInfo);
	}

	/**
	 * 是否显示发起流程还款按钮
	 */
	public ShowButtonFilter showBottun = new ShowButtonFilter() {

		@Override
		public boolean filter(Object param) {
			Object[] params = (Object[]) param;
			if (params[6].equals(StatusContexts.O2O_NEW)) {
				return true;
			} else {
				return false;
			}
		}
	};
	/**
	 * 是否显示查看回款流程
	 */
	public ShowButtonFilter showBottunDetail = new ShowButtonFilter() {

		@Override
		public boolean filter(Object param) {
			Object[] params = (Object[]) param;
			if (params[6].equals(StatusContexts.O2O_NEW)) {
				return false;
			} else {
				return true;
			}
		}
	};

	@RequestMapping("/chushihua")
	public BaseRestResult<String> chushihua() {
		List<Object[]> loanDataIds = service.getLoanDataId();
		if (loanDataIds != null && loanDataIds.size() > 0) {
			for (int i = 0; i < loanDataIds.size(); i++) {
				List<O2oBadRecordEntity> records = service.getBadRecord(loanDataIds.get(i)[0].toString());
				if (records != null && records.size() > 0) {
					for (int j = 0; j < records.size(); j++) {
						O2oBadRecordEntity badRecordEntity = records.get(j);
						if (j == 0) {
							O2oEaLoanDataEnity dataEnity = service.findByLoanDataId(loanDataIds.get(i)[0].toString());
							BigDecimal nowArrears = calculationNowArrears(dataEnity.getPayAmount(), dataEnity.getPayDate(), badRecordEntity.getPayTime(), badRecordEntity.getPayAmount());
							badRecordEntity.setNowArrears(nowArrears);
							service.updateByBadRecordID(badRecordEntity);
							if (j == (records.size() - 1)) {
								dataEnity.setPayAreas(nowArrears);
								service.updateEaLoanData(dataEnity);
							}
						} else {
							O2oBadRecordEntity beforBadRecordEntity = records.get(j - 1);
							BigDecimal nowArrears = calculationNowArrears(beforBadRecordEntity.getNowArrears(), beforBadRecordEntity.getPayTime(), badRecordEntity.getPayTime(), badRecordEntity.getPayAmount());
							badRecordEntity.setNowArrears(nowArrears);
							service.updateByBadRecordID(badRecordEntity);
							if (j == (records.size() - 1)) {
								O2oEaLoanDataEnity dataEnity = service.findByLoanDataId(loanDataIds.get(i)[0].toString());
								dataEnity.setPayAreas(nowArrears);
								service.updateEaLoanData(dataEnity);
							}
						}
					}
				}
			}
		}
		return BaseRestResult.info("初始化数据成功").andRefresh();
	}

	@RequestMapping("/chushihuaAll")
	public BaseRestResult<String> chushihuaALL(String loanDataId) {
		if (!StringUtil.isEmpty(loanDataId)) {
			List<O2oBadRecordEntity> records = service.getBadRecord(loanDataId);
			if (records != null && records.size() > 0) {
				for (int j = 0; j < records.size(); j++) {
					O2oBadRecordEntity badRecordEntity = records.get(j);
					if (j == 0) {
						O2oEaLoanDataEnity dataEnity = service.findByLoanDataId(loanDataId);
						BigDecimal nowArrears = calculationNowArrears(dataEnity.getPayAmount(), dataEnity.getPayDate(), badRecordEntity.getPayTime(), badRecordEntity.getPayAmount());
						badRecordEntity.setNowArrears(nowArrears);
						service.updateByBadRecordID(badRecordEntity);
						if (j == (records.size() - 1)) {
							dataEnity.setPayAreas(nowArrears);
							service.updateEaLoanData(dataEnity);
						}
					} else {
						O2oBadRecordEntity beforBadRecordEntity = records.get(j - 1);
						BigDecimal nowArrears = calculationNowArrears(beforBadRecordEntity.getNowArrears(), beforBadRecordEntity.getPayTime(), badRecordEntity.getPayTime(), badRecordEntity.getPayAmount());
						badRecordEntity.setNowArrears(nowArrears);
						service.updateByBadRecordID(badRecordEntity);
						if (j == (records.size() - 1)) {
							O2oEaLoanDataEnity dataEnity = service.findByLoanDataId(loanDataId);
							dataEnity.setPayAreas(nowArrears);
							service.updateEaLoanData(dataEnity);
						}
					}
				}
				service.updatePayAreas(loanDataId);
				service.updateLoad(loanDataId);
			} else {
				O2oEaLoanDataEnity dataEnity = service.findByLoanDataId(loanDataId);
				dataEnity.setPayAreas(new BigDecimal(0));
				dataEnity.setPaymentAmount(new BigDecimal(0));
				service.updateEaLoanData(dataEnity);
			}
		} else {
			chushihua();// 初始化
			service.updateLoadTatol();// 校正所有代偿回款总额
			service.updatePayAreasAll();// 校正所有最后一次回款余额
		}
		return BaseRestResult.info("校正数据成功").andRefresh();
	}

	public BigDecimal calculationNowArrears(BigDecimal now, Date fkDate, Date zCfDate, BigDecimal payAmount) {
		BigDecimal nowArrears = new BigDecimal(0);
		Calendar nowDate = Calendar.getInstance(), oldDate = Calendar.getInstance();
		nowDate.setTime(zCfDate);// 本次回款时间
		oldDate.setTime(fkDate);// 上一次回款时间
		long timeNow = nowDate.getTimeInMillis();
		long timeOld = oldDate.getTimeInMillis();
		long nowTime = (timeNow - timeOld) / (1000 * 60 * 60 * 24);// 化为天
		nowTime = nowTime < 0 ? 0 : nowTime;// 如果天数小于0，值为零
		nowArrears = now.add(now.multiply(new BigDecimal(0.15 / 360)).multiply(new BigDecimal(nowTime))).subtract(payAmount);
		return nowArrears;
	}

	/**
	 * @Description:
	 * 				<p>
	 *               校正所有代偿回款总额
	 *               </p>
	 * @author CXW
	 * @date 2017年3月29日 上午9:59:41
	 * @version V1.0
	 */
	@RequestMapping("/updateLoadTatol")
	public BaseRestResult<String> updateLoadTatol() {
		service.updateLoadTatol();
		return BaseRestResult.info("校正数据成功").andRefresh();
	}

	@Autowired
	private O2oPayServiceImpl o2oPayServiceImpl;

	/**
	 * @Description:
	 * 				<p>
	 *               代偿详情
	 *               </p>
	 * @author CXW
	 * @date 2017年4月20日 上午10:49:13
	 * @version V1.0
	 */

	@RequestMapping("/badloan_detail")
	public BaseRestResult<String> badloan_detail(O2oLoanForm loanForm) {
		O2oEaLoanDataEnity dataEnity = service.findByIdOrRecordIdDetail(loanForm);
		String endLoanTime = "";
		if (dataEnity != null && !StringUtils.isEmpty(dataEnity.getId())) {
			endLoanTime = service.findEndReloanTime(dataEnity.getId());
		}

		O2oPayEntity o2oPayEntity = new O2oPayEntity();
		if (dataEnity != null && !StringUtils.isEmpty(dataEnity.getPayId())) {
			o2oPayEntity = o2oPayServiceImpl.findById(dataEnity.getPayId());
		}
		O2oSettleVo vo = new O2oSettleVo();
		vo.setEaLoadId(dataEnity.getId());
		O2oSettleEntity o2oSettleEntity = o2oSettleService.findEntity(vo);
		ViewContext.put("dataEnity", dataEnity);
		ViewContext.put("o2oPayEntity", o2oPayEntity);
		ViewContext.put("endLoanTime", endLoanTime);
		ViewContext.put("o2oSettleEntity", o2oSettleEntity);
		return new HtmlRestResult("badloan/badloan_detail");
	}

	@RequestMapping("/badLoanPage")
	public PaginationRestResult findBadLoanPage(O2oBadLoanPageVo entity) {
		entity.setPageSize(10000);
		String o2ourl = "/badloan/badLoanPage";
		String idCard = entity.getIdCard() == null ? "" : entity.getIdCard();
		String spouseIdCard = entity.getSpouseIdCard() == null ? "" : entity.getSpouseIdCard();
		o2ourl = UrlUtil.appendUrl(o2ourl, "idCard", idCard);
		o2ourl = UrlUtil.appendUrl(o2ourl, "spouseIdCard", spouseIdCard);
		PageResult<Object[]> pageResult = service.getBadLoanPage(entity);
		String titles[] = { "贷款单号", "终端贷款单号", "借款人姓名", "代偿类型", "贷款类型", "代偿或付款时间", "代偿总额(元)", "代偿回款总额(元)", "代偿余额(元)", "最后一次回款时间" };
		Format[] formats = new Format[] { null, null, null, null, null, null, new DecimalFormat(",##0.00"), new DecimalFormat(",##0.00"), new DecimalFormat(",##0.00"), null };
		SelectDataOption[] selectDataOptions = { null, null, null, new SelectDataOption("OTO_PAY_TYPE"), new SelectDataOption("BAD_LOAN_TYPE"), null, null, null, null, null };
		PaginationInfo o2oPagingInfo = new PaginationInfo(pageResult, titles, "");
		o2oPagingInfo.setBuildPagingNavigation(false);
		o2oPagingInfo.setFirstRenderColumnIndex(2);
		o2oPagingInfo.setSelectDataOptions(selectDataOptions);
		o2oPagingInfo.setRendTo("#bad_loan_page");
		o2oPagingInfo.setFormats(formats);
		ViewContext.put("vo", entity);
		ViewContext.put("paginationInfo", o2oPagingInfo);
		return PaginationRestResult.buildPaginationRestResult(o2oPagingInfo);
	}

	/**
	 * @Description:
	 * 				<p>
	 *               代还款详情按钮
	 *               </p>
	 * @author CXW
	 * @date 2017年5月18日 下午3:14:16
	 * @version V1.0
	 */
	@RequestMapping("/buttons")
	public BaseRestResult<String> bottons(O2oLoanForm loanForm) {
		O2oEaLoanDataEnity dataEnity = service.findByIdOrRecordIdDetail(loanForm);
		List<Button> bottons = new ArrayList<>();
		Button detail = ButtonHelper.createOpenButton("回款明细", "/badloan/alllist?loanDataId=" + dataEnity.getId());
		Button start_upButton = ButtonHelper.createAjaxButton("发起回款流程", "/rbadloan/start?bankLoanId=" + dataEnity.getId(), "startUpBadLoan");
		Button upLoaDataYe = ButtonHelper.createAjaxButton("校正数据", "/rbadloan/chushihuaAll?loanDataId=" + dataEnity.getId(), "updateNowAreas");
		Button start = null;
		if (dataEnity != null && !dataEnity.getLoanType().equals("LXDC")) {
			start = ButtonHelper.createAjaxButton("启动代偿分期", "/rback/start?loanApplyNo=" + loanForm.getLoanApplyNo(), "startBack");
		}
		Button startSettle = ButtonHelper.createAjaxButton("启动代偿结清", "/rsettle/startUp?eaLoadId=" + dataEnity.getId(), "updateDataSettle");
		bottons.add(detail);
		bottons.add(start_upButton);
		bottons.add(upLoaDataYe);
		bottons.add(start);
		bottons.add(startSettle);
		ViewContext.put("buttons", bottons);
		return new HtmlRestResult("badloan/detail_button");
	}

	/**
	 * @Description:
	 * 				<p>
	 *               作废页面/否决页面
	 *               </p>
	 * @author CXW
	 * @date 2017年6月8日 上午10:41:53
	 * @version V1.0
	 */
	@RequestMapping("/cacle")
	public BaseRestResult<String> cacle(String loanapplyNo, String tType) {
		O2oCacleEntity cacleEntity = o2oCancleServiceImpl.findByLoanapplyId(loanapplyNo);
		O2oLoanapplyEntity loan = o2oLoanapplyService.findById(loanapplyNo);
		String urlHtml = "cacle/veto";
		if (StatusContexts.CANCLE_TYPE.equals(tType)) {
			urlHtml = "cacle/cacle";
		} else if (StatusContexts.VETO_TYPE.equals(tType)) {
			urlHtml = "cacle/veto";
		} else if (StatusContexts.CANCLE_CREDIT.equals(tType)) {
			urlHtml = "cacle/cacleCredit";
		} else if (StatusContexts.NEWCANCLE_TYPE.equals(tType)){
			urlHtml = "cacle/flow_cacle";
		}
		ViewContext.put("tType", tType);
		ViewContext.put("loanapplyNo", loanapplyNo);
		ViewContext.put("loan", loan);
		ViewContext.put("cacleEntity", cacleEntity);
		return HtmlRestResult.popHtmlFragment(urlHtml);
	}

	/**
	 * @Description:
	 * 				<p>
	 *               确认作废，保存作废/ 确认否决，保存否决
	 *               </p>
	 * @author CXW
	 * @date 2017年6月8日 上午10:41:53
	 * @version V1.0
	 */
	@RequestMapping("/cacleSuer")
	public BaseRestResult<String> cacleSuer(O2oCacleEntity cacleEntity) {
		String remark = "";
		String promptMessage = "";
		String promptMessage1 = "";
		if (!StringUtil.isEmpty(cacleEntity.gettType()) && StatusContexts.VETO_TYPE.equals(cacleEntity.gettType())) {
			if (StringUtil.isEmpty(cacleEntity.gettWhy())) {
				return BaseRestResult.warn("请选择否决原因");
			}
			if (StringUtil.isEmpty(cacleEntity.gettVetoTerm())) {
				return BaseRestResult.warn("请选择贷款限制期限");
			}
			cacleEntity.settSysType(StatusContexts.CANCLE_TYPE_FJ);
			promptMessage = "确认否决";
			promptMessage1 = "否决信息录入失败，请联系管理员";
			remark = "请填写否决备注";
		} else {
			cacleEntity.settSysType(StatusContexts.CANCLE_TYPE_SG);
			promptMessage = "确认作废";
			promptMessage1 = "作废信息录入失败，请联系管理员";
			remark = "请填写作废原因";
		}
		if (StringUtil.isEmpty(cacleEntity.gettRemark())) {
			return BaseRestResult.warn(remark);
		}
		StringBuffer url = new StringBuffer("/workflowsubmit/invalidLoanLapply?loanapplyNo=");
		O2oLoanapplyEntity loan = loanService.findById(cacleEntity.getLoanapplyNo());
		if (StatusContexts.CANCLE_CREDIT.equals(cacleEntity.gettType())) {
			cacleEntity.settType("O2OZX");
			url = new StringBuffer("/rbadloan/cancleDetail?loanapplyNo=");
		} else {
			cacleEntity.settType(loan.getWfType());
		}
		url.append(cacleEntity.getLoanapplyNo());
		User user = UserHolder.getUser();
		Date date = new Date();
		if (StringUtil.isEmpty(cacleEntity.getId())) {// 如果之前保存成功不进if，之前保存不成功进入if
			cacleEntity.settOpername(user.getCname());
			cacleEntity.settOperno(user.getNo());
			cacleEntity.settTime(date);
			cacleEntity.settIsSuccess(StatusContexts.O2O_NO);
			log.info("作废记录对象：{}", cacleEntity);
			int j = o2oCancleServiceImpl.insertCalcle(cacleEntity);
			if (j <= 0) {
				log.info("作废单号：[{}],记录不成功，不能作废，请重新操作。", cacleEntity.getLoanapplyNo());
				return BaseRestResult.warn(promptMessage1).andRefresh();
			}
		}
		url.append("&id=");
		url.append(cacleEntity.getId());
		return BaseRestResult.confirm(promptMessage).andActionAjaxLoad(url.toString());
	}

	@RequestMapping("/cancleDetail")
	public BaseRestResult<String> cancleDetail(O2oCacleEntity cacleEntity) {
		O2oCacleTForm cacleEntity1 = o2oCancleServiceImpl.findByLoanapplyTId(cacleEntity.getLoanapplyNo());
		String urlHtml = "";
		if (null != cacleEntity1 && StringUtil.isEmpty(cacleEntity1.gettVetoTerm())) {
			urlHtml = "cacle/cancleDetail";
		} else if (null != cacleEntity1 && !StringUtil.isEmpty(cacleEntity1.gettVetoTerm())) {
			urlHtml = "cacle/vetoDetail";
		} else {
			urlHtml = "cacle/null";
		}
		ViewContext.put("cacleEntity", cacleEntity1);
		return new HtmlRestResult(urlHtml);
	}

	public void getBankAccount() {
		List<String> bankcards = bankAccountService.getBankAccount();
		ViewContext.put("bankAccountList", bankcards);
	}

	/**
	 * 作废按钮
	 * 
	 * @return
	 */
	@RequestMapping("/creditCancle")
	public BaseRestResult<String> creditCancle(O2oCacleEntity payform) {
		com.eascs.admin.common.vo.ModelResult<Boolean> r = o2oCancleServiceImpl.creditCancle(payform);
		if (r.isSuccess()) {
			return BaseRestResult.info("作废成功").andRefresh();
		} else {
			log.info("作废单号：[{}]失败, message:[{}]", payform.getLoanapplyNo(), r.getErrMsg());
			return BaseRestResult.warn("作废失败").andRefresh();
		}
	}
	
	/**
	 * 新建状态自动作废按钮
	 * 
	 * @return
	 */
	@RequestMapping("/loanNewCancle")
	public BaseRestResult<String> loanNewCancle() {
		com.eascs.admin.common.vo.ModelResult<Boolean> r = iCancelService.loanNewCancle();
		if (r.isSuccess()) {
			return BaseRestResult.info("作废成功");
		} else {
			log.info("作废失败, message:[{}]", r.getErrMsg());
			return BaseRestResult.warn("作废失败,message:"+r.getErrMsg());
		}
	}
	
	@RequestMapping("/liquidate")
	public BaseRestResult<List<Object[]>> referrer(String name) {
		List<Object[]> data = new ArrayList<>();
		if (StringUtil.hasText(name)) {
			ModelResult<List<Object[]>> da = sysOrgService.get380Employee(name);
			log.info("是否调用成功：【{}】，接口返回信息：【{}】", da.isSuccess(), da.getErrMsg());
			data = da.getModel();
		}
		return BaseRestResult.buildRestResult(data);
	}
}
